package com.iguo.news.util;

import org.apache.commons.io.FileUtils;
import org.mozilla.universalchardet.UniversalDetector;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class NewsTextToDatabaseImporter {
  // 数据库配置 - 添加了serverTimezone参数
  private static final String DB_URL = "jdbc:mysql://localhost:3306/tushu?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC";
  private static final String DB_USER = "root";
  private static final String DB_PASSWORD = "20040302gyx";
  // 文件目录路径
  private static final String DIRECTORY_PATH = "E:\\Desktop\\大数据\\三级项目数据集\\data\\文本分类语料库\\政治505";
  private static final String type = "政治";
  private static final int BATCH_SIZE = 100;
  public static void main(String[] args) {
    try {
      Class.forName("com.mysql.cj.jdbc.Driver");
      List<File> txtFiles = getTxtFiles(DIRECTORY_PATH);
      System.out.println("找到 " + txtFiles.size() + " 个文本文件");
      List<NewsArticle> articles = parseTextFiles(txtFiles);
      if (!articles.isEmpty()) {
        int inserted = batchInsertNews(articles);
        System.out.println("成功插入 " + inserted + " 条新闻记录");
      } else {
        System.out.println("没有找到可处理的TXT文件");
      }
    } catch (ClassNotFoundException e) {
      System.err.println("无法加载JDBC驱动");
      e.printStackTrace();
    }
  }

  private static List<File> getTxtFiles(String directoryPath) {
    List<File> txtFiles = new ArrayList<>();
    File dir = new File(directoryPath);
    if (dir.exists() && dir.isDirectory()) {
      File[] files = dir.listFiles((d, name) -> name.toLowerCase().endsWith(".txt"));
      if (files != null) {
        Collections.addAll(txtFiles, files);
      }
    }
    return txtFiles;
  }

  private static List<NewsArticle> parseTextFiles(List<File> txtFiles) {
    List<NewsArticle> articles = new ArrayList<>();

    for (File file : txtFiles) {
      try {
        String content = detectAndReadFile(file);
        System.out.println(content);

        NewsArticle article = parseNewsArticle(content);
        if (article != null) {
          articles.add(article);
          System.out.println("成功解析文章: " + file.getName());
        } else {
          System.out.println("未能解析文件: " + file.getName());
        }
      } catch (Exception e) {
        System.err.println("处理文件失败: " + file.getName());
        e.printStackTrace();
      }
    }
    return articles;
  }

  private static String detectAndReadFile(File file) throws IOException {
    byte[] bytes = FileUtils.readFileToByteArray(file);
    // 使用juniversalchardet检测编码
    UniversalDetector detector = new UniversalDetector(null);
    detector.handleData(bytes, 0, bytes.length);
    detector.dataEnd();
    String encoding = detector.getDetectedCharset();
    detector.reset();

    if (encoding != null) {
      try {
        return new String(bytes, encoding);
      } catch (UnsupportedEncodingException e) {
        // 继续尝试其他编码
      }
    }
    // 如果自动检测失败，尝试常见中文编码
    String[] encodings = {"UTF-8", "GBK", "GB18030", "ISO-8859-1"};
    for (String enc : encodings) {
      try {
        String content = new String(bytes, enc);
        if (content.contains("《") &&content.contains("（") &&content.contains("，") &&content.contains("【") && content.contains("】")) {
          return content;
        }
      } catch (UnsupportedEncodingException e) {
      }
    }
    return new String(bytes);
  }

  private static NewsArticle parseNewsArticle(String text) {
    NewsArticle article = new NewsArticle();
    article.setNewContent(text);
    return article;
  }

  private static int batchInsertNews(List<NewsArticle> articles) {

    String sql = "INSERT INTO `new` (new_content,new_type) VALUES (?,?)";
    int totalInserted = 0;

    try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
      conn.setAutoCommit(false);

      try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
        int count = 0;

        for (NewsArticle article : articles) {
          pstmt.setString(1, article.getNewContent());
          pstmt.setString(2, type);
          pstmt.addBatch();

          if (++count % BATCH_SIZE == 0) {
            int[] batchResult = pstmt.executeBatch();
            totalInserted += batchResult.length;
            conn.commit();
            System.out.println("已提交一批数据: " + batchResult.length + " 条记录");
          }
        }

        // 提交剩余批次
        int[] lastBatchResult = pstmt.executeBatch();
        totalInserted += lastBatchResult.length;
        conn.commit();
        System.out.println("提交最后一批数据: " + lastBatchResult.length + " 条记录");

      } catch (SQLException e) {
        conn.rollback();
        System.err.println("批量插入失败，已回滚");
        throw e;
      }

    } catch (SQLException e) {
      System.err.println("数据库操作失败");
      e.printStackTrace();
      return 0;
    }

    return totalInserted;
  }

  static class NewsArticle {
    private String newContent;

    public String getNewContent() {
      return newContent;
    }

    public void setNewContent(String newContent) {
      this.newContent = newContent;
    }
  }
}